var U : Any->Any;
U = $u:Any =>u(u);
var Y = $f:Any => U($x:Any => f($v:Any => x(x)(v)));

var move = $src:String => $tgt:String => $n:Int => {
    print("move plate ");
    print(n);
    print(" from ");
    print(src);
    print(" to ");
    println(tgt);
    0;
};

var hanoi = $h:String->String->String->Int->Int => $src:String => $tgt:String => $aux:String => $n:Int => {
    if (n == 1) {
        move(src)(tgt)(1);
    }
    else {
        h(src)(aux)(tgt)(n-1);
        move(src)(tgt)(n);
        h(aux)(tgt)(src)(n-1);
    };
};

Y(hanoi)("a")("c")("b")(4);

